﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using Borg.Properties;

namespace Borg
{
    public class FilePersistor : Persistor
    {
        protected internal FilePersistor(Runtime runtime, string path)
            : base(runtime, path)
        { }

        protected override void InternalSave()
        {
            var contractSerializer = new NetDataContractSerializer();
            var directoryName = System.IO.Path.GetDirectoryName(Path);
            
            if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
                Directory.CreateDirectory(directoryName);

            using (var fileStream = new FileStream(Path, FileMode.Create))
            using (XmlWriter xmlWriter = XmlDictionaryWriter.CreateBinaryWriter(fileStream))
                contractSerializer.WriteObject(xmlWriter, data);

            isModified = false;
        }

        protected override bool InternalLoad()
        {
            if (!File.Exists(Path))
            {
                data = new Dictionary<string, object>();
                return false;
            }
            
            try
            {
                using (var fileStream = new FileStream(Path, FileMode.Open))
                using (XmlReader xmlReader = XmlDictionaryReader.CreateBinaryReader(
                        fileStream, new XmlDictionaryReaderQuotas()))
                    data = (Dictionary<string, object>) new NetDataContractSerializer().ReadObject(xmlReader);

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log(
                    VerbosityLevel.Normal,
                    LogType.Error,
                    this,
                    Messages.DataStore_ErrorOnLoadingFile,
                    (object) Path,
                    (object) ex);
                
                data = new Dictionary<string, object>();
            }

            return false;
        }
    }
}
